import datetime
import os
import shutil
import sys
import time

# from tqdm import tqdm
from alive_progress import alive_bar
import tpys
import zips


scflag = 'yssc'
had_ysdir = "已压缩"  # 放置已压缩的压缩包
restart_number = 2  # 重试次数

tpgs = 'png,jpg,jpeg,JPEG,JPG,PNG,bmp,BMP'
ysgs = 'rar,zip,RAR,ZIP,7z,7Z'


def strofsize(integer, remainder, level):
    if integer >= 1024:
        remainder = integer % 1024
        integer //= 1024
        level += 1
        return strofsize(integer, remainder, level)
    else:
        return integer, round(remainder / 1024, 2), level


def StrOfSize(size):
    units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
    integer, remainder, level = strofsize(size, 0, 0)
    if level + 1 > len(units):
        level = -1
    return '{} {}'.format(integer + remainder, units[level])


def find_dir(mydiry, ysdir=had_ysdir):  # 获取含图片的文件夹,排除已压缩
    file_list2 = []
    for folderName, subfolders, filenames in os.walk(mydir):
        for filename in filenames:
            if os.path.splitext(filename)[1].replace(".", "") is not None and os.path.splitext(filename)[1].replace(
                    ".", "") in tpgs and os.path.splitext(filename)[1].replace(".", "") != '':
                pd1 = 0
                file_temp1 = os.path.split(
                    os.path.join(folderName, filename))[0]
                if len(file_list2) == 0 and ysdir not in file_temp1:
                    file_list2.append(file_temp1)
                    break
                for list in file_list2:
                    if file_temp1 == list:
                        pd1 = 1
                        break
                if pd1 == 0 and ysdir not in file_temp1:
                    file_list2.append(file_temp1)
    return file_list2


def find_zip(mydir, yysdir=had_ysdir):  # 寻找符合条件的压缩包
    file_list = []
    file_list2 = []
    for folderName, subfolders, filenames in os.walk(mydir):
        for filename in filenames:
            if os.path.splitext(filename)[1].replace(".", "") is not None and os.path.splitext(filename)[1].replace(
                    ".", "") in ysgs and os.path.splitext(filename)[1].replace(".", "") != '':
                if yysdir not in os.path.join(folderName, filename):
                    # 寻找所有压缩包，去除在已压缩目录下的压缩包
                    file_list.append(os.path.join(folderName, filename))
    for flist in file_list:  # 寻找符合条件的压缩包
        if zips.pd_ziprar(flist) == 1:
            file_list2.append(flist)
    return list(set(file_list) ^ set(file_list2))


def unzips(file_list, code=0, flag='123'):  # 解压压缩包
    zip_number = 0
    for flist in file_list:
        if zips.un_ziprar(flist, code=code, flag=scflag) == 0:
            zip_number += 1
    return zip_number


def find_fdir(dir_list1, dir):  # 寻找含图片的上层目录（但去除最根目录），先压缩
    dir_list2 = [dir]
    for dir1 in dir_list1:
        for dir2 in dir_list1:
            if dir1 == dir2:
                break
            elif dir2 in dir1:
                pd1 = 0
                if len(dir_list2) == 0:
                    dir_list2.append(dir2)
                    break
                for list in dir_list2:
                    if dir2 == list:
                        pd1 = 1
                        break
                if pd1 == 0:
                    dir_list2.append(dir2)
                    break
    if len(dir_list2) != 0:
        dir_list2.remove(dir)
    return dir_list2


def find_fdir2(list1, dir_list2):  # 寻找最接近上层目录的目录，用于打包
    for dir2 in dir_list2:
        if dir2 in list1:
            parent_path = list1
            while parent_path != dir2:
                parent_path1 = parent_path
                parent_path = os.path.dirname(parent_path)
            return parent_path1
    return 1


def getdirsize(mydir):  # 获取文件夹大小
    size = 0
    for root, dirs, files in os.walk(mydir):
        size += sum([os.path.getsize(os.path.join(root, name)) for name in files])
    return size


def find_img(mydir):  # 寻找该文件夹内部图片的详细地址
    file_list1 = []
    for folderName, subfolders, filenames in os.walk(mydir):
        for filename in filenames:
            if os.path.splitext(filename)[1].replace(".", "") is not None and os.path.splitext(filename)[1].replace(
                    ".", "") in tpgs and os.path.splitext(filename)[1].replace(".", "") != '' and filename not in "_pl2temp":
                file_list1.append(os.path.join(folderName, filename))
    return file_list1


def ys_rootdir(dir_list1, dir_list2, rootdir, model, works, code, flag=scflag, code2=1, reys=restart_number):  # 压缩图片并打包
    pd1 = 0
    pd2 = 0
    if len(dir_list1) != 0:
        # with tqdm(total=len(dir_list1), ncols=70) as pbar:
        with alive_bar(len(dir_list1), bar='blocks') as bar:
            for list1 in dir_list1:
                print("开始压缩" + list1 + "内部图片")
                st_size = getdirsize(list1)
                pd2 = tpys.dirys(mydir=list1, model=model, works=works, code=code, flag=flag)
                if pd2 != 0:
                    print(list1 + "压缩完毕,共出现" + str(pd2) + "处错误")  # 重试
                    while(pd2 != 0 and pd1 < reys):
                        print("开始重试，第" + str(pd1) + "次")
                        pd1 += 1
                        pd2 = tpys.dirys(mydir=list1, model=model, works=works, code=code, flag=flag)
                        if pd2 == 0:
                            break
                    if pd2 != 0:
                        print(list1 + "压缩失败")
                    else:
                        if code == 1:
                            end_size = getdirsize(list1)
                            if end_size < st_size:
                                print(list1 + "压缩完毕")
                                print("共节约" + StrOfSize(st_size - end_size) + "空间，压缩率" + '{:.0%}'.format(1 - end_size / st_size))
                            else:
                                print("反而没有节约空间")
                        else:
                            print(list1 + "压缩完毕(不删除原始文件)")
                elif pd2 == 0:
                    if code == 1:
                        end_size = getdirsize(list1)
                        if end_size < st_size:
                            print(list1 + "压缩完毕")
                            print("共节约" + StrOfSize(st_size - end_size) + "空间，压缩率" + '{:.0%}'.format(1 - end_size / st_size))
                        else:
                            print("反而没有节约空间")
                    else:
                        print(list1 + "压缩完毕(不删除原始文件)")
                if code2 == 1:  # code3=1 不需要打包
                    bar()
                    continue
                ys_dir = find_fdir2(list1, dir_list2)
                if ys_dir != 1:
                    print("开始打包成zip")
                    if zips.zip_file(src_dir=ys_dir, code=code, flag=scflag) != 1:
                        print(list1 + "打包完成")
                    else:
                        print(list1 + "打包失败")
                else:
                    ys_dir = find_fdir2(list1, [mydir])  # 文件夹在根目录下
                    if ys_dir != 1:
                        if zips.zip_file(src_dir=ys_dir, code=code, flag=scflag) != 1:
                            print(list1 + "打包完成")
                            # 不是二级目录的话移动到指定位置
                            new_dir = mydir + "\\" + had_ysdir + "\\"
                            if os.path.isdir(new_dir):
                                pass
                            else:
                                os.mkdir(new_dir)
                            try:
                                if os.path.exists(ys_dir + ".zip"):
                                    shutil.move(ys_dir + ".zip", new_dir)
                                    print(ys_dir + ".zip" + "移动文件成功")
                                else:
                                    print("移动文件失败")
                            except BaseException:
                                print("移动文件失败")
                        else:
                            print(list1 + "打包失败")
                # pbar.update(1)  # 更新进度条
                bar()
                print("\n")


def ys_nrootdir(dir_list1, model, works, code, flag='no'):  # 压缩图片
    pd2 = 0
    if len(dir_list1) != 0:
        for list1 in dir_list1:
            print("开始压缩" + list1 + "内部图片")
            st_size = getdirsize(list1)
            pd2 = tpys.dirys(mydir=list1, model=model,
                             works=works, code=code, flag=flag)
            if pd2 != 0:
                print(list1 + "压缩完毕,共出现" + str(pd2) + "处错误")
            elif pd2 == 0:
                if code == 1:
                    end_size = getdirsize(list1)
                    if end_size < st_size:
                        print(list1 + "压缩完毕")
                        print("共节约" + StrOfSize(st_size - end_size) + "空间，压缩率" + '{:.0%}'.format(1 - end_size / st_size))
                    else:
                        print("反而没有节约空间")
                else:
                    print(list1 + "压缩完毕")

# 输入开始


while True:  # 判断输入地址是否正确，输入cs可退出
    mydir = input("请输入待处理文件地址：")
    if not os.path.isdir(mydir):
        if mydir != 'cs':
            print("请输入正确的地址")
        else:
            print("退出")
            input("按任意键结束")
            sys.exit()
    else:
        break

print("0 不删除原始压缩包，新压缩包重命名  1 删除原始压缩包，新压缩包不重命名")
while True:
    code1 = input("是否删除原压缩包（默认代码1）：")
    if code1 != '0' and code1 != '1' and code1 != '' and code1 != 'cs':
        print("请输入正确的代码")
    elif code1 == '1' or code1 == '':
        code1 = '1'
        break
    elif code1 == '0':
        break
    elif code1 == 'cs':
        print("退出")
        input("按任意键结束")
        sys.exit()

print("0 智能判断压缩方式  1 采用png压缩（若图片非png则调用jpg压缩）")
print("2 转换为WEBP       3 采用jpg模式1压缩（jpegtran）")
print("4 采用jpg模式2压缩（mozcjpeg）（默认调用）")
while True:
    model1 = input("选择压缩模式(默认代码4)：")
    if model1 != '0' and model1 != '1' and model1 != '2' and model1 != '3' and model1 != '4' and model1 != '' and model1 != 'cs':
        print("请输入正确的代码")
    elif model1 == '4' or model1 == '':
        model1 = '4'
        break
    elif model1 == '1' or model1 != '2' or model1 != '3' or model1 != '0':
        break
    elif model1 == 'cs':
        print("退出")
        input("按任意键结束")
        sys.exit()

while True:
    workstemp = input("输入压缩线程数（默认代码12,值小于32）：")
    if not str.isdigit(workstemp) and workstemp != '':
        if int(workstemp) > 32:
            print("请输入正确的数字")
    elif workstemp == '':
        work_num = 12
        break
    elif workstemp == 'cs':
        print("退出")
        input("按任意键结束")
        sys.exit()
    else:
        work_num = int(workstemp)
        break

while True:
    code2temp = input("是否删除原图片文件（y,n）（不删除不打包）（默认代码y）：")
    if code2temp != 'y' and code2temp != 'n' and code2temp != '' and code2temp != 'cs':
        print("请输入正确的代码")
    elif code2temp == 'y' or code2temp == '':
        code2 = 1
        break
    elif code2temp == 'n':
        code2 = 0
        break
    elif code2temp == 'cs':
        print("退出")
        input("按任意键结束")
        sys.exit()
code3 = 1
if code2 == 1:
    # code3=0 zip打包
    # code3=1 不打包
    while True:
        code3temp = input("是否进行打包（y,n）（默认代码y）：")
        if code3temp != 'y' and code3temp != 'n' and code3temp != '' and code3temp != 'cs':
            print("请输入正确的代码")
        elif code3temp == 'y' or code3temp == '':
            code3 = 0
            break
        elif code3temp == 'n':
            code3 = 1
            break
        elif code3temp == 'cs':
            print("退出")
            input("按任意键结束")
            sys.exit()
# 输入结束

# 解压处理
st = time.time()
zip_list1 = find_zip(mydir)  # 寻找压缩包
print("已找到" + str(len(zip_list1)) + "个待处理压缩包")
if len(zip_list1) != 0:
    print("开始进行解压")
    zip_numbers = unzips(zip_list1, code=int(code1), flag=scflag)  # 解压
    end = time.time()
    print("共" + str(len(zip_list1)) + "个待处理压缩包；" + "已解压" + str(zip_numbers) + "个待处理压缩包" + ";共耗时" + str(format(end - st, '.1f')) + 's')
# 解压结束

# 进入图片处理
st = time.time()
dir_list1 = find_dir(mydir)

# 判断有无需要处理的文件和根目录是否需要处理
pd1 = 0
mydirflag = 0
if len(dir_list1) != 0:
    for list1 in dir_list1:
        if list1 == mydir:
            pd1 = 1
            break
    if pd1 == 1 and len(dir_list1) != 0:
        dir_list1.remove(mydir)
        mydirflag = 1
else:
    print("无需要处理的文件夹")
    input("按任意键结束")
    sys.exit()

dir_list2 = []
dir_list2 = find_fdir(dir_list1, mydir)  # 寻找含图片的上层目录（但去除最根目录），先压缩
dir_list3 = list(set(dir_list1) ^ set(dir_list2))  # 求差集，获取优先处理的文件夹,list是系统变量


if len(dir_list3) != 0:
    ys_rootdir(dir_list1=dir_list3, dir_list2=dir_list2, rootdir=mydir, model=int(model1), works=int(work_num), code=int(code2), flag=scflag, code2=code3)
# 压缩最底层文件夹图片
if len(dir_list2) != 0:
    ys_nrootdir(dir_list1=dir_list2, model=int(model1), works=int(work_num), code=int(code2))
# 压缩上一层级文件夹内部图片

if mydirflag == 1:
    ys_nrootdir(dir_list1=[mydir], model=int(model1), works=int(work_num), code=int(code2))


end = time.time()
print("全部图片处理完毕，共耗时" + str(datetime.timedelta(seconds=end - st)))

input("按任意键结束")

# pyinstaller --hidden-import=queue -i   favicon.ico -F main.py
# 123
